package org.dolphin.action.inventory;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.dolphin.base.bean.FlatProductAttributeVO;
import org.dolphin.base.bean.FlatProductItemSearchVO;
import org.dolphin.base.bean.FlatProductItemVO;
import org.dolphin.base.bean.ProductAttributePriceVO;
import org.dolphin.base.bean.ProductAttributeVO;
import org.dolphin.base.constant.Status;
import org.dolphin.base.json.PaginationBean;
import org.dolphin.base.json.StatusBean;
import org.dolphin.dao.impl.ProductItemPriceLookup;
import org.dolphin.entity.inventory.Product;
import org.dolphin.entity.inventory.ProductAttribute;
import org.dolphin.service.ProductService;
import org.dolphin.service.UomService;
import org.dolphin.util.ExceptionHelper;
import org.dolphin.util.Nvl;
import org.dolphin.util.Pagination;
import org.hibernate.criterion.Order;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

@ParentPackage(value = "custom-default")
@Namespace(value = "/inventory/productAttribute")
@InterceptorRefs(value = {@InterceptorRef(value = "customStack")})
public class ProductAttributeAction extends ActionSupport {
  private static final long serialVersionUID = 5660619310180891512L;
  private ProductService productService;
  private Integer page;
  private Integer rows;
  private String sidx;
  private String sord;
  private PaginationBean pagination;
  private StatusBean status;
  private ProductAttributeVO productAttribute;
  private UomService uomService;
  private ProductItemPriceLookup priceLookup;

  @Action(value = "addProductAttribute", results = @Result(name = "success", location = "addProductAttribute.jsp"))
  public String addProductAttribute() {
    return SUCCESS;
  }

  @Action(value = "createProductAttribute", results = @Result(name = "success", params = {"root",
      "status"}, type = "json"))
  public String createProductAttribute() {
    boolean error = false;
    String msg = "";
    status = new StatusBean();
    try {
      String productId = productAttribute.getProductId();
      Product product = getProductService().loadProduct(productId);
      ProductAttribute attribute = new ProductAttribute();
      attribute.setProduct(product);
      attribute.setName(productAttribute.getAttributeName());
      attribute.setStockKeepingUnit(productAttribute.getSku());
      attribute.setAdjustmentRetailPrice(Nvl.nvl(productAttribute.getAdjustmentRetailPrice()));
      getProductService().createProductAttribute(attribute);
    } catch (Exception e) {
      error = true;
      msg = ExceptionHelper.getRootCause(e).getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      }
    }
    return SUCCESS;
  }

  @Action(value = "editProductAttribute", results = @Result(name = "success", location = "editProductAttribute.jsp"))
  public String editProductAttribute() {
    return SUCCESS;
  }

  public Integer getPage() {
    return page;
  }

  public PaginationBean getPagination() {
    return pagination;
  }

  public ProductItemPriceLookup getPriceLookup() {
    return priceLookup;
  }

  public ProductAttributeVO getProductAttribute() {
    return productAttribute;
  }

  @Action(value = "getProductAttributes", results = @Result(name = "success", params = {"root",
      "pagination"}, type = "json"))
  public String getProductAttributes() {
    String productId = productAttribute.getProductId();
    List<Order> orders = null;
    if (StringUtils.hasText(getSidx())) {
      orders = new ArrayList<Order>(1);
      Order order = ObjectUtils.nullSafeEquals("desc", getSord()) ? Order.desc(getSidx()) : Order
          .asc(getSidx());
      orders.add(order);
    }
    List<FlatProductAttributeVO> results = getProductService().getProductAttributes(productId,
        page, rows, orders);
    Long records = getProductService().getProductAttributesCount(productId);
    Integer total = Pagination.calculateTotalPage(records, getRows());
    pagination = new PaginationBean();
    pagination.setPage(getPage());
    pagination.setRecords(records);
    pagination.setTotal(total);
    pagination.setRows(results);
    return SUCCESS;
  }

  @Action(value = "getProductItems", results = @Result(name = "success", params = {"root",
      "pagination"}, type = "json"))
  public String getProductItems() {
    List<Order> orders = null;
    if (StringUtils.hasText(getSidx())) {
      orders = new ArrayList<Order>(1);
      Order order = ObjectUtils.nullSafeEquals("desc", getSord()) ? Order.desc(getSidx()) : Order
          .asc(getSidx());
      orders.add(order);
    }
    List<FlatProductItemVO> results = getProductService().getProductItems(page, rows, orders);
    Long records = getProductService().getProductItemsCount();
    Integer total = Pagination.calculateTotalPage(records, getRows());
    pagination = new PaginationBean();
    pagination.setPage(getPage());
    pagination.setRecords(records);
    pagination.setTotal(total);
    pagination.setRows(results);
    return SUCCESS;
  }

  @Action(value = "getProductItemSearch", results = @Result(name = "success", params = {"root",
      "pagination"}, type = "json"))
  public String getProductItemSearch() {
    List<Order> orders = null;
    if (StringUtils.hasText(getSidx())) {
      orders = new ArrayList<Order>(1);
      Order order = ObjectUtils.nullSafeEquals("desc", getSord()) ? Order.desc(getSidx()) : Order
          .asc(getSidx());
      orders.add(order);
    }
    List<FlatProductItemSearchVO> results = getProductService().getProductItemSearch(page, rows,
        orders);
    Long records = getProductService().getProductItemSearchCount();
    Integer total = Pagination.calculateTotalPage(records, getRows());
    pagination = new PaginationBean();
    pagination.setPage(getPage());
    pagination.setRecords(records);
    pagination.setTotal(total);
    pagination.setRows(results);
    return SUCCESS;
  }

  public ProductService getProductService() {
    return productService;
  }

  public Integer getRows() {
    return rows;
  }

  public String getSidx() {
    return sidx;
  }

  public String getSord() {
    return sord;
  }

  public StatusBean getStatus() {
    return status;
  }

  public UomService getUomService() {
    return uomService;
  }

  @Action(value = "loadProductAttribute", results = @Result(name = "success", params = {"root",
      "productAttribute"}, type = "json"))
  public String loadProductAttribute() {
    String id = productAttribute.getId();
    productAttribute = getProductService().getProductAttribute(id);
    return SUCCESS;
  }

  @Action(value = "lookupProductItemPrice", results = @Result(name = "success", params = {"root",
      "status"}, type = "json"))
  public String lookupProductItemPrice() {
    status = new StatusBean();
    String msg = "";
    boolean error = false;
    try {
      Assert.notNull(priceLookup);
      Date priceItemDate = priceLookup.getPriceItemDate();
      ProductAttribute attribute = priceLookup.getProductAttribute();
      if (attribute == null || attribute.getId() == null) {
        throw new IllegalArgumentException(getText("error.required",
            new String[] {getText("title.product")}));
      }
      Assert.notNull(priceItemDate,
          getText("error.required", new String[] {getText("field.price.date")}));
      attribute = getProductService().loadProductAttribute(attribute.getId());
      ProductAttributePriceVO priceVO = getProductService().lookupProductAttributePrice(attribute,
          priceItemDate);
      Assert.notNull(priceVO, getText("error.price.not.found"));
      status.addAttr("productAttribute", priceVO);
    } catch (Exception e) {
      error = true;
      msg = ExceptionHelper.getRootCause(e).getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      }
    }
    return SUCCESS;
  }

  public void setPage(Integer page) {
    this.page = page;
  }

  public void setPagination(PaginationBean pagination) {
    this.pagination = pagination;
  }

  public void setPriceLookup(ProductItemPriceLookup priceLookup) {
    this.priceLookup = priceLookup;
  }

  public void setProductAttribute(ProductAttributeVO productAttribute) {
    this.productAttribute = productAttribute;
  }

  public void setProductService(ProductService productService) {
    this.productService = productService;
  }

  public void setRows(Integer rows) {
    this.rows = rows;
  }

  public void setSidx(String sidx) {
    this.sidx = sidx;
  }

  public void setSord(String sord) {
    this.sord = sord;
  }

  public void setStatus(StatusBean status) {
    this.status = status;
  }

  public void setUomService(UomService uomService) {
    this.uomService = uomService;
  }

  @Action(value = "updateProductAttribute", results = @Result(name = "success", params = {"root",
      "status"}, type = "json"))
  public String updateProductAttribute() {
    boolean error = false;
    String msg = "";
    status = new StatusBean();
    ProductAttribute pa = null;
    try {
      String id = productAttribute.getId();
      pa = getProductService().fetchProductAttribute(id);
      pa.setVersion(productAttribute.getVersion());
      pa.setStockKeepingUnit(productAttribute.getSku());
      pa.setName(productAttribute.getAttributeName());
      pa.setAdjustmentRetailPrice(Nvl.nvl(productAttribute.getAdjustmentRetailPrice()));
      getProductService().updateProductAttribute(pa);
    } catch (Exception e) {
      error = true;
      msg = ExceptionHelper.getRootCause(e).getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      } else {
        if (pa != null) {
          status.addAttr("version", pa.getVersion());
        }
      }
    }
    return SUCCESS;
  }

  @Action(value = "viewProductItemSearch", results = @Result(name = "success", location = "viewProductItemSearch.jsp"))
  public String viewProductItemSearch() {
    return SUCCESS;
  }
}
